package com.ztgf.order.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.commodity.models.bo.OrderCommodityHighBO;
import com.ztgf.commodity.models.dto.CommodityComboRelationDTO;
import com.ztgf.commodity.models.dto.CommodityInfoDTO;
import com.ztgf.commodity.models.dto.CommoditySpecificationRelationDTO;
import com.ztgf.commodity.models.service.ICommodityComboRelationService;
import com.ztgf.commodity.models.service.ICommodityInfoService;
import com.ztgf.commodity.models.service.ICommoditySpecificationRelationService;
import com.ztgf.commodity.models.vo.CommodityPriceVO;
import com.ztgf.commodity.models.vo.OrderHighShopVo;
import com.ztgf.common.utils.CustomizeUtil;
import com.ztgf.db.utils.RedisUtil;
import com.ztgf.message.model.bo.MessageAnnouncementSaveBO;
import com.ztgf.message.model.constant.MessageTopicType;
import com.ztgf.message.model.dto.ResponseDTO;
import com.ztgf.message.model.enums.MessageEnum;
import com.ztgf.message.model.service.IKafkaProducerService;
import com.ztgf.order.common.config.YmlConfig;
import com.ztgf.order.mapper.OrderCommodityRelationMapper;
import com.ztgf.order.models.bo.OrderCommodityRelationSaveBO;
import com.ztgf.order.models.dto.*;
import com.ztgf.order.models.enums.BargainStateEnum;
import com.ztgf.order.models.service.*;
import com.ztgf.order.models.vo.OrderCommodityDetailVO;
import com.ztgf.order.models.vo.OrderInfoVO;
import com.ztgf.shopping.models.dto.shop.ShopSysInvoiceDTO;
import com.ztgf.shopping.models.service.shop.IShopInfoService;
import com.ztgf.shopping.models.service.shop.IShopShoppingCartService;
import com.ztgf.shopping.models.vo.shop.ShopInfoVO;
import com.ztgf.sms.models.bo.SmsInfoSaveBO;
import com.ztgf.sms.models.service.ISmsInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.ztgf.common.utils.UtilConstants.*;

/**
 * 订单商品表控制器
 *
 * @author chenyu.wang
 * @Date 2020-06-03 15:55:40
 */
@Slf4j
@DubboService
@Lazy
public class OrderCommodityRelationServiceImpl extends ServiceImpl<OrderCommodityRelationMapper, OrderCommodityRelationDTO> implements IOrderCommodityRelationService {

    @Resource
    private YmlConfig ymlConfig;

    @DubboReference
    private ICommodityInfoService commodityInfoService;

    @DubboReference
    private IShopInfoService shopInfoService;

    @Autowired
    @Lazy
    private IOrderInfoService orderInfoService;

    @DubboReference
    private ICommoditySpecificationRelationService commoditySpecificationRelationService;

    @DubboReference
    private ICommodityComboRelationService commodityComboRelationService;

    @DubboReference
    private IShopShoppingCartService shopShoppingCartService;

    @Autowired
    private IOrderPayRelationService orderPayRelationService;

    @Autowired
    private IOrderContractParamRelationService orderContractParamRelationService;

    @Autowired
    private RedisUtil redisUtil;

    @DubboReference
    private IKafkaProducerService kafkaProducerService;

    @DubboReference
    private ISmsInfoService smsInfoService;

    @Autowired
    private IOrderInvoiceService orderInvoiceService;

    @Autowired
    private IOrderPaymentScaleService orderPaymentScaleService;

    @Autowired
    private IOrderPaymentTypeService orderPaymentTypeService;

    /**
     * 还原库存 数据库 和 redis都应相应增加
     *
     * @param orderId
     */
    public void restoreCommodityStock(Long orderId) {
        List<OrderCommodityRelationDTO> orderCommodityRelationDTOList = getByOrderId(orderId);
        for (OrderCommodityRelationDTO orderCommodityRelationDTO : orderCommodityRelationDTOList) {
            String commodityAttr = orderCommodityRelationDTO.getAtrrId();
            Long commodityId = orderCommodityRelationDTO.getCommodityId();
            int num = orderCommodityRelationDTO.getNum();
            Long currentNum = redisUtil.incrCommodityNum(commodityId, commodityAttr, num);//redis重新增加
            commodityInfoService.updateBackInventory(commodityId, commodityAttr, Math.toIntExact(currentNum));
        }
    }

    @Override
    public List<CommodityPriceVO> getViewsGoods() {
        List<CommodityPriceVO> result = new ArrayList<>();
        // 查询商品浏览量排名
        List<OrderHighShopVo> viewsGoods = baseMapper.getViewsGoods();
        if (CustomizeUtil.listIsNull(viewsGoods)) {
            return result;
        }
        for (OrderHighShopVo viewsGood : viewsGoods) {
            // 商品id
            Long goodsId = viewsGood.getId();
            CommodityPriceVO commodityPriceVO = commodityInfoService.getByIdOtherInterface(goodsId);
            if (commodityPriceVO == null) {
                continue;
            }
            if (result.size() > 3) {
                break;
            }
            result.add(commodityPriceVO);
        }
        return result;
    }

    /**
     * 同步技术服务费（卖家）
     * @Author :liyang
     * @return
     */
    @Override
    public List<ShopSysInvoiceDTO> synchronizationShopSysInvoiceSell() {
        return baseMapper.synchronizationShopSysInvoiceSell();
    }

    /**
     * 同步技术服务费（买家申请平台砍价成功）
     * @return
     */
    @Override
    public List<ShopSysInvoiceDTO> synchronizationShopSysInvoiceBuy() {
        return baseMapper.synchronizationShopSysInvoiceBuy();
    }

    @Override
    public boolean add(OrderCommodityRelationSaveBO saveBO) {
        OrderCommodityRelationDTO dto = new OrderCommodityRelationDTO();
        BeanUtils.copyProperties(saveBO, dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        return this.insert(dto);
    }

    /**
     * 根据订单查询响应的商品
     *
     * @return
     */
    public List<OrderCommodityRelationDTO> getByOrderId(Long orderId) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq("order_id", orderId);
        return baseMapper.selectList(wrapper);
    }

    /**
     * 添加
     *
     * @param orderInfoVO
     * @return
     */
    public List<String> addByOrderInfo(OrderInfoVO orderInfoVO) {
        List<String> ids = new ArrayList<>();
        for (OrderCommodityDetailVO orderCommodityDetailVO : orderInfoVO.getOrderCommodityDetailVOList()) {
            if(null != orderCommodityDetailVO.getPurchaseCommodityType() && orderCommodityDetailVO.getPurchaseCommodityType() ==  BargainStateEnum.PURCHASE_COMMODITY_OK.getCode()){
                OrderCommodityRelationDTO dto = new OrderCommodityRelationDTO();
                Long commodityId = orderCommodityDetailVO.getCommodityId();//商品id
                int commodityNum = Integer.parseInt(orderCommodityDetailVO.getCommodityNum());//商品数量
                dto.setCommodityCategoryId(orderCommodityDetailVO.getCategoryId());
                dto.setCommodityId(commodityId);
                dto.setPrice(orderCommodityDetailVO.getSingleCommodityPrice());
                dto.setNum(commodityNum);
                dto.setMoeny(orderCommodityDetailVO.getCommodityTotal());
                dto.setDiscountMoney(orderCommodityDetailVO.getCommodityDiscountTotal());
                dto.setSingleActualMoney(orderCommodityDetailVO.getSingleCommodityRealTotal());
                dto.setSingleCommissionMoney(orderCommodityDetailVO.getSingleCommissionMoney());
                dto.setActualMoney(orderCommodityDetailVO.getCommodityRealTotal());
                dto.setDiscountType(orderCommodityDetailVO.getDiscountsType());
                dto.setTaxRate(orderCommodityDetailVO.getTaxRate());
                dto.setBrandName(orderCommodityDetailVO.getBrandName());
                dto.setUnitName(orderCommodityDetailVO.getUnitName());
                dto.setAttrName(orderCommodityDetailVO.getAttrName());
                dto.setCommodityName(orderCommodityDetailVO.getCommodityName());
                dto.setOrderId(orderInfoVO.getId());
                dto.setWarrantyMonth(orderCommodityDetailVO.getWarrantyMonth());
                dto.setCommissionMoney(orderCommodityDetailVO.getCommissionMoney());
                dto.setCommissionRate(orderCommodityDetailVO.getCommissionRate());
                dto.setWholesaleNum(orderCommodityDetailVO.getWholesaleNum());
                dto.setWholesalePrice(orderCommodityDetailVO.getWholesalePrice());
                dto.setSendDays(orderCommodityDetailVO.getSendDays());
                dto.setStockDays(orderCommodityDetailVO.getStockDays());
                dto.setOtherDiscountPrice(orderCommodityDetailVO.getCommodityDiscountTotal());
                dto.setPurchaseCommodityType(orderCommodityDetailVO.getPurchaseCommodityType());
                dto.setPlatBargainStatus(orderCommodityDetailVO.getPlatBargainStatus());
                dto.setPurchaseCommodityBargainId(orderCommodityDetailVO.getPurchaseCommodityBargainId());
                dto.setPurchaseFeeMoneyScalePrice(orderCommodityDetailVO.getPurchaseFeeMoneyScalePrice());
                dto.setOrganiserUserName(orderCommodityDetailVO.getOrganiserUserName());
                dto.setPurchaseFeeMoney(orderCommodityDetailVO.getPurchaseFeeMoney());
                dto.setPurchaseInfoId(orderCommodityDetailVO.getPurchaseInfoId());
                Long id = ymlConfig.getPkId();
                ids.add(id + "");
                dto.setId(id);

                this.insert(dto);
            }else {
                OrderCommodityRelationDTO dto = new OrderCommodityRelationDTO();
                Long commodityId = orderCommodityDetailVO.getCommodityId();//商品id
                String attrOrComId = orderCommodityDetailVO.getAttrIds();//规格或者套餐ids
                String[] split = attrOrComId.split(",");
                Arrays.sort(split);
                attrOrComId = String.join(",", split);//给属性id排序
                int commodityNum = Integer.parseInt(orderCommodityDetailVO.getCommodityNum());//商品数量
                dto.setCommodityCategoryId(orderCommodityDetailVO.getCategoryId());
                dto.setCommodityId(commodityId);
                dto.setAtrrId(attrOrComId);
                dto.setPrice(orderCommodityDetailVO.getSingleCommodityPrice());
                dto.setNum(commodityNum);
                dto.setMoeny(orderCommodityDetailVO.getCommodityTotal());
                dto.setDiscountMoney(orderCommodityDetailVO.getCommodityDiscountTotal());
                dto.setSingleActualMoney(orderCommodityDetailVO.getSingleCommodityRealTotal());
                dto.setSingleCommissionMoney(orderCommodityDetailVO.getSingleCommissionMoney());
                dto.setActualMoney(orderCommodityDetailVO.getCommodityRealTotal());
                dto.setDiscountType(orderCommodityDetailVO.getDiscountsType());
                dto.setTaxRate(orderCommodityDetailVO.getTaxRate());
                dto.setBrandName(orderCommodityDetailVO.getBrandName());
                dto.setUnitName(orderCommodityDetailVO.getUnitName());
                dto.setAttrName(orderCommodityDetailVO.getAttrName());
                dto.setCommodityName(orderCommodityDetailVO.getCommodityName());
                dto.setOrderId(orderInfoVO.getId());
                dto.setWarrantyMonth(orderCommodityDetailVO.getWarrantyMonth());
                dto.setCommissionMoney(orderCommodityDetailVO.getCommissionMoney());
                dto.setCommissionRate(orderCommodityDetailVO.getCommissionRate());
                dto.setWholesaleNum(orderCommodityDetailVO.getWholesaleNum());
                dto.setWholesalePrice(orderCommodityDetailVO.getWholesalePrice());
                dto.setSendDays(orderCommodityDetailVO.getSendDays());
                dto.setStockDays(orderCommodityDetailVO.getStockDays());
                dto.setOtherDiscountPrice(orderCommodityDetailVO.getCommodityDiscountTotal());
                Long id = ymlConfig.getPkId();
                ids.add(id + "");
                dto.setId(id);
                this.insert(dto);

                //去掉库存
                CommoditySpecificationRelationDTO commoditySpecificationRelationDTO = commoditySpecificationRelationService.selectByCommodityAndAttrIds(commodityId, attrOrComId);
                if (null == commoditySpecificationRelationDTO) {
                    CommodityComboRelationDTO commodityComboRelationDTO = commodityComboRelationService.selectByCommodityAndComIds(Long.parseLong(attrOrComId), commodityId);
                    int inventory = commodityComboRelationDTO.getInventoryNumber() - commodityNum;
                    if (inventory < 0) {
                        log.error("库存不足commodityId:" + commodityId + "---attrOrComId:" + attrOrComId);
                        throw new RuntimeException("库存不足");
                    }
//                Long aLong = redisUtil.decryCommodityNum(commodityId, attrOrComId, commodityNum, commodityComboRelationDTO.getInventoryNumber());
//                if ((Long.parseLong("-1") == aLong)) {//库存不足
//                    throw new RuntimeException("库存不足");
//                }
                    Integer inventoryNumberWarning = commodityComboRelationDTO.getInventoryNumberWarning();//预警数量
                    if (inventory <= inventoryNumberWarning) {//发站内信 发短信
                        sendInventoryNumberWarning(orderInfoVO.getSellShopId());
                    }
                    commodityComboRelationDTO.setInventoryNumber(inventory);
                    commodityComboRelationService.updateById(commodityComboRelationDTO);//更新库存
                } else {

                    int inventory = commoditySpecificationRelationDTO.getInventoryNumber() - commodityNum;
                    if (inventory < 0) {
                        log.error("库存不足commodityId:" + commodityId + "---attrOrComId:" + attrOrComId);
                        throw new RuntimeException("库存不足");
                    }
//                Long aLong = redisUtil.decryCommodityNum(commodityId, attrOrComId, commodityNum, commoditySpecificationRelationDTO.getInventoryNumber());
//                if ((Long.parseLong("-1") == aLong)) {//库存不足
//                    throw new RuntimeException("库存不足");
//                }
                    Integer inventoryNumberWarning = commoditySpecificationRelationDTO.getInventoryNumberWarning();//预警数量
                    if (inventory <= inventoryNumberWarning) {//发站内信 发短信
                        sendInventoryNumberWarning(orderInfoVO.getSellShopId());
                    }
                    commoditySpecificationRelationDTO.setInventoryNumber(inventory);
                    commoditySpecificationRelationService.updateById(commoditySpecificationRelationDTO);//更新库存
                }
            }
            //删除已买购物车的数据
            log.info("删除已买购物车的数据 : {}", orderInfoVO);
            shopShoppingCartService.deleteByCid(orderInfoVO.getBuyerShopId(), orderCommodityDetailVO.getCommodityId(), orderCommodityDetailVO.getAttrIds());
        }
        return ids;
    }

    private void sendInventoryNumberWarning(Long shopId) {
        ResponseDTO responseDTO = new ResponseDTO();
        responseDTO.setMessageId(shopId + "");
        MessageAnnouncementSaveBO messageAnnouncementSaveBO = new MessageAnnouncementSaveBO();
        messageAnnouncementSaveBO.setType(MessageEnum.SYS_MESSAGE.getCode());
        messageAnnouncementSaveBO.setShopId(shopId);
        messageAnnouncementSaveBO.setTitle("库存不足");
        messageAnnouncementSaveBO.setContent("库存不足");
        messageAnnouncementSaveBO.setTextType(1);
        messageAnnouncementSaveBO.setJumpType(MessageEnum.INVENTORY_NUMBER_WARNING.getCode() + "");
        messageAnnouncementSaveBO.setShopType(MessageEnum.SHOP_TYPE_2.getCode());
        //messageAnnouncementSaveBO.setKey( + "");
        responseDTO.setData(messageAnnouncementSaveBO);
        kafkaProducerService.senMessage(JSON.toJSONString(responseDTO), MessageTopicType.COMMENT_MESSAGE_TOPIC);

        //发送短信
        SmsInfoSaveBO smsInfoSaveBO = new SmsInfoSaveBO();
        ShopInfoVO shopInfoVO = shopInfoService.selectVoById(shopId);
        smsInfoSaveBO.setMobile(shopInfoVO.getMobile());
        smsInfoSaveBO.setType(3);
        smsInfoSaveBO.setName(shopInfoVO.getShopName());
        smsInfoSaveBO.setContent("尊敬的" + shopInfoVO.getShopName() + "，您的商品库存以达到您设置的商品库存报警，请上线处理。");
        try {
            smsInfoService.saveThreshold(smsInfoSaveBO);
        } catch (Exception e) {
            log.error("发送库存短信异常" + e.getMessage());
        }
    }

    @Override
    public List<OrderHighShopVo> getOrderHighCommodity(OrderCommodityHighBO orderCommodityHighBO) {
        return baseMapper.selectHighShop(orderCommodityHighBO);
    }


    @Override
    public List<CommodityPriceVO> getHighShop(OrderCommodityHighBO orderCommodityHighBO) {
        orderCommodityHighBO.setPageNo(orderCommodityHighBO.getPageNo() - 1);
        orderCommodityHighBO.setPageSize(10);
        List<OrderHighShopVo> orderHighShop = this.getOrderHighCommodity(orderCommodityHighBO);
        List<CommodityPriceVO> commodityPriceVOS = new ArrayList<>();
        for (OrderHighShopVo orderHighShopVo : orderHighShop) {
            CommodityPriceVO commodityPriceVO = commodityInfoService.getByIdOtherInterface(orderHighShopVo.getId());
            CommodityInfoDTO dtoA = commodityInfoService.selectById(commodityPriceVO.getId());
            if (dtoA != null && dtoA.getIsPublish() == 1) {
                commodityPriceVOS.add(commodityPriceVO);
            }
        }
        return commodityPriceVOS;
    }


    @Transactional
    @Override
    public boolean updateOrderGoodsPrice(Long shopId, Long id, BigDecimal price) {
        OrderCommodityRelationDTO dto = this.selectById(id);
        log.info("1----------------------orderid="+dto.getOrderId()+"----------------综合优惠："+dto.getDiscountMoney()+"-----------------批发优惠："+dto.getOtherDiscountPrice());
        if (dto == null) {
            return false;
        }
//        if (price.compareTo(dto.getMoeny()) > 0) {
//            throw new RuntimeException("实付价格不能大于商品总价,修改失败!");
//        }
        price.setScale(TWO, BigDecimal.ROUND_UP);
        //新的单价 =  （修改的实付金额 + 优惠金额）/ 数量
        BigDecimal totalPrice = price.add(dto.getDiscountMoney());

        totalPrice.setScale(TWO, BigDecimal.ROUND_UP);
        //数量
        BigDecimal num = new BigDecimal(dto.getNum()).setScale(TWO, BigDecimal.ROUND_UP);
        //新的单价
        BigDecimal actuallyPaidUnitPrice = totalPrice.divide(num, TWO).setScale(TWO, BigDecimal.ROUND_UP);
        //重新计算单商品佣金金额
        BigDecimal newOnePrice = actuallyPaidUnitPrice.multiply(dto.getCommissionRate()).setScale(TWO, BigDecimal.ROUND_UP);
        //重新计算总佣金金额
        BigDecimal newTatal = price.multiply(dto.getCommissionRate()).setScale(TWO, BigDecimal.ROUND_UP);
        //计算优惠,单价 * 数量 - 实付 = 优惠
        BigDecimal newDiscount = dto.getMoeny().subtract(price);
        //原来的实付-改价的实付
        BigDecimal ap = dto.getActualMoney().subtract(price);
        //重新优惠的 / 数量
        BigDecimal bp = ap.divide(num, TWO).setScale(TWO, BigDecimal.ROUND_UP);
        OrderCommodityRelationDTO updateDto = new OrderCommodityRelationDTO();
        updateDto.setId(dto.getId());
        updateDto.setUpdateUserId(shopId);
        updateDto.setActualMoney(price);//总实付金额
        updateDto.setChangePrice(price);//修改的价格
        updateDto.setIsChangePrice(ONE);//是否改价，0否，1是
        updateDto.setSingleCommissionMoney(newOnePrice);//单商品佣金金额
        updateDto.setCommissionMoney(newTatal);//总商品佣金金额
        updateDto.setDiscountMoney(newDiscount);//总优惠金额
        updateDto.setSingleCommodityDiscountChangePrice(bp);//改价部分 单商品的优惠价格
        log.info("2----------------------orderid="+dto.getOrderId()+"-----小计："+dto.getMoeny()+"-----综合优惠："+dto.getDiscountMoney()+"-----批发优惠："+dto.getOtherDiscountPrice()+"-----改价："+price);
        //updateDto.setChangeDiscountPrice(dto.getDiscountMoney().subtract(dto.getOtherDiscountPrice()));// 卖家改价后优惠金额
        updateDto.setChangeDiscountPrice(dto.getMoeny().subtract(dto.getOtherDiscountPrice()).subtract(price));// 卖家改价后优惠金额
        boolean update = this.updateById(updateDto);
        if (!update) {
            return false;
        }
        //重新计算订单总实付金额
        BigDecimal acountPrice = new BigDecimal(ZERO);//总实付金额
        //重新计算订单总佣金
        BigDecimal newCommission = new BigDecimal(ZERO);//总佣金
        //新的总优惠金额
        BigDecimal newDiscountPrice = new BigDecimal(ZERO);
        //查同一订单商品
        Wrapper<OrderCommodityRelationDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", dto.getOrderId());
        List<OrderCommodityRelationDTO> list = this.selectList(wrapper);
        if (isNull(list)) {
            throw new RuntimeException("修改商品金额失败!");
        }
        for (OrderCommodityRelationDTO relationDTO : list) {
            acountPrice = acountPrice.add(relationDTO.getActualMoney());
            newCommission = newCommission.add(relationDTO.getCommissionMoney());
            newDiscountPrice = newDiscountPrice.add(relationDTO.getDiscountMoney());
            //更改订单总金额
            OrderInfoDTO orderInfo = new OrderInfoDTO();
            orderInfo.setId(dto.getOrderId());//订单id
            orderInfo.setActualMoney(acountPrice);//订单实付金额
            orderInfo.setCommissionMoney(newCommission);//订单总佣金
            orderInfo.setLastCommissionMoney(newCommission);//修改实际佣金
            orderInfo.setDiscountMoney(newDiscountPrice);//总优惠
            boolean updateOrder = orderInfoService.updateById(orderInfo);
            if (!updateOrder) {
                throw new RuntimeException("修改订单金额失败!");
            }
            // 修改订单发票金额
            boolean b1 = this.modifyInvoiceAmount(dto.getOrderId(), acountPrice);
            if (!b1) {
                throw new RuntimeException("修改订单发票金额失败!");
            }
            //修改订单支付金额
            OrderInfoDTO order = orderInfoService.selectById(dto.getOrderId());

            //查询订单支付
            Wrapper<OrderPayRelationDTO> orderPayRelation = new EntityWrapper<>();
            orderPayRelation.eq("order_id", order.getId());
            List<OrderPayRelationDTO> payList = orderPayRelationService.selectList(orderPayRelation);

            if (order.getPayType() == ZERO) {
                //查询赊销支付方式
                OrderPaymentTypeDTO orderPaymentTypeDTO = orderPaymentTypeService.getOrderPaymentByOrderIdAndPaymentType(dto.getOrderId(),2);
                if(null != orderPaymentTypeDTO){
                    if (isNull(payList)) {
                        log.info("暂无订单支付信息，修改失败!");
                        throw new RuntimeException("暂无订单支付信息，修改失败!");
                    }
                    updatePaymentScalePrice(order,order.getActualMoney());
                }else {
                    //全款不算首付款，直接改支付金额
                    OrderPayRelationDTO one = orderPayRelationService.selectOne(orderPayRelation);
                    OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                    updateOrderPay.setId(one.getId());//id
                    updateOrderPay.setRealPayMoney(order.getActualMoney());//实付金额
                    updateOrderPay.setCommissionMoney(order.getCommissionMoney());//佣金
                    boolean b = orderPayRelationService.updateById(updateOrderPay);
                    if (!b) {
                        throw new RuntimeException("修改订单支付金额失败!");
                    }
                }
            } else {
                //分期付款需要重新计算首付款金额
                CommodityInfoDTO goods = commodityInfoService.selectById(dto.getCommodityId());
                //首款比例
                BigDecimal g = new BigDecimal(goods.getFirstBalance()).setScale(TWO, BigDecimal.ROUND_UP);
                //尾款比例
                BigDecimal f = new BigDecimal(goods.getTailBalance()).setScale(TWO, BigDecimal.ROUND_UP);
                //首款
                BigDecimal firstActualMoney = order.getActualMoney()
                        .multiply(g.divide(new BigDecimal(100), TWO));
                //尾款
                BigDecimal tailActualMoney = order.getActualMoney()
                        .multiply(f.divide(new BigDecimal(100), TWO));
                //首款分润
                BigDecimal firstCommission = order.getCommissionMoney()
                        .multiply(g.divide(new BigDecimal(100), TWO));
                //尾款分润
                BigDecimal tailCommission = order.getCommissionMoney()
                        .multiply(f.divide(new BigDecimal(100), TWO));
                if (isNull(payList)) {
                    throw new RuntimeException("暂无订单支付信息，修改失败!");
                }
                for (OrderPayRelationDTO payRelationDTO : payList) {
                    if (payRelationDTO.getPeriods() == ONE) {
                        //首款
                        OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                        updateOrderPay.setId(payRelationDTO.getId());//id
                        updateOrderPay.setRealPayMoney(firstActualMoney);//实付金额
                        updateOrderPay.setCommissionMoney(firstCommission);//佣金
                        boolean b = orderPayRelationService.updateById(updateOrderPay);
                        if (!b) {
                            throw new RuntimeException("修改订单支付金额失败!");
                        }
                    } else {
                        //尾款
                        OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                        updateOrderPay.setId(payRelationDTO.getId());//id
                        updateOrderPay.setRealPayMoney(tailActualMoney);//实付金额
                        updateOrderPay.setCommissionMoney(tailCommission);//佣金
                        boolean b = orderPayRelationService.updateById(updateOrderPay);
                        if (!b) {
                            throw new RuntimeException("修改订单支付金额失败!");
                        }
                    }
                }
                // 查询订单合同
                Wrapper<OrderContractParamRelationDTO> contractWrapper = new EntityWrapper<>();
                contractWrapper.eq("order_id", order.getId());
                OrderContractParamRelationDTO orderContractParamRelationDTO = orderContractParamRelationService.selectOne(contractWrapper);
                if (null == orderContractParamRelationDTO) {
                    log.info("暂无订单合同信息!");
                    throw new RuntimeException("暂无订单合同信息,修改失败!");
                }
                OrderContractParamRelationDTO updateContract = new OrderContractParamRelationDTO();
                updateContract.setId(orderContractParamRelationDTO.getId());
                updateContract.setFirstMoney(firstActualMoney);
                updateContract.setTailMoney(tailActualMoney);
                orderContractParamRelationService.updateById(updateContract);
            }
        }
        return true;
    }

    /*
     * @description:修改订单询价商品价格
     * @author: chenyu.wang
     * @date: 2020-08-18
     * @param:
     * @return:
     */
    @Transactional
    @Override
    public boolean updateOtherGoodsPrice(Long shopId, Long id, BigDecimal price) {
        OrderCommodityRelationDTO dto = this.selectById(id);
        if (dto == null) {
            return false;
        }
        //价格处理
        BigDecimal inPrice = price.setScale(TWO, BigDecimal.ROUND_UP);
        //新的单价 =  （修改的实付金额 + 优惠金额）/ 数量
        //BigDecimal totalPrice = inPrice.add(dto.getDiscountMoney());

        //BigDecimal inTotalPrice = totalPrice.setScale(TWO, BigDecimal.ROUND_UP);
        BigDecimal inTotalPrice=inPrice;
        //数量
        BigDecimal num = new BigDecimal(dto.getNum()).setScale(TWO, BigDecimal.ROUND_UP);
        //新的单价
        BigDecimal actuallyPaidUnitPrice = inTotalPrice.divide(num, TWO).setScale(TWO, BigDecimal.ROUND_UP);
        //重新计算单商品佣金金额
        BigDecimal newOnePrice = actuallyPaidUnitPrice.multiply(dto.getCommissionRate());
        //重新计算总佣金金额
        BigDecimal newTatal = price.multiply(dto.getCommissionRate());
        //计算优惠,单价 * 数量 - 实付 = 优惠
        BigDecimal total = actuallyPaidUnitPrice.multiply(num);

        BigDecimal newDiscount = total.subtract(inPrice);

        OrderCommodityRelationDTO updateDto = new OrderCommodityRelationDTO();
        updateDto.setId(dto.getId());
        updateDto.setUpdateUserId(shopId);
        updateDto.setMoeny(total);//总价
        updateDto.setActualMoney(price);//总实付金额
        updateDto.setChangePrice(price);//修改的价格
        updateDto.setIsChangePrice(ONE);//是否改价，0否，1是
        updateDto.setSingleCommissionMoney(newOnePrice);//单商品佣金金额
        updateDto.setCommissionMoney(newTatal);//总商品佣金金额
        updateDto.setDiscountMoney(newDiscount);//总优惠金额
        updateDto.setPrice(actuallyPaidUnitPrice);//单价
        if (dto.getActualMoney().compareTo(BigDecimal.ZERO) > 0) {
            //原来的实付-改价的实付
            BigDecimal ap = dto.getActualMoney().subtract(price);
            //重新优惠的 / 数量
            BigDecimal bp = ap.divide(num, TWO).setScale(TWO, BigDecimal.ROUND_UP);
            updateDto.setSingleCommodityDiscountChangePrice(bp);
        }
        boolean update = this.updateById(updateDto);
        if (!update) {
            log.info("修改订单商品失败!");
            return false;
        }
        //重新计算订单总实付金额
        BigDecimal acountPrice = new BigDecimal(ZERO);//总实付金额
        //重新计算订单总佣金
        BigDecimal newCommission = new BigDecimal(ZERO);//总佣金
        //新的总优惠金额
        BigDecimal newDiscountPrice = new BigDecimal(ZERO);
        //总价
        BigDecimal orderPrice = new BigDecimal(ZERO);
        //查同一订单商品
        Wrapper<OrderCommodityRelationDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", dto.getOrderId());
        List<OrderCommodityRelationDTO> list = this.selectList(wrapper);
        if (isNull(list)) {
            log.info("修改商品金额失败!");
            throw new RuntimeException("修改商品金额失败!");
        }
        for (OrderCommodityRelationDTO relationDTO : list) {
            acountPrice = acountPrice.add(relationDTO.getActualMoney());
            newCommission = newCommission.add(relationDTO.getCommissionMoney());
            newDiscountPrice = newDiscountPrice.add(relationDTO.getDiscountMoney());
            orderPrice = orderPrice.add(relationDTO.getMoeny());
            //更改订单总金额
            OrderInfoDTO orderInfo = new OrderInfoDTO();
            orderInfo.setId(dto.getOrderId());//订单id
            orderInfo.setActualMoney(acountPrice);//订单实付金额
            orderInfo.setCommissionMoney(newCommission);//订单总佣金
            orderInfo.setLastCommissionMoney(newCommission);//最后佣金
            orderInfo.setDiscountMoney(newDiscountPrice);//总优惠
            orderInfo.setTotalMoney(orderPrice);//总价
            boolean updateOrder = orderInfoService.updateById(orderInfo);
            if (!updateOrder) {
                log.info("修改订单金额失败!");
                throw new RuntimeException("修改订单金额失败!");
            }
            // 修改订单发票金额
            boolean b1 = this.modifyInvoiceAmount(dto.getOrderId(), acountPrice);
            if (!b1) {
                throw new RuntimeException("修改订单发票金额失败!");
            }
            //修改订单支付金额
            OrderInfoDTO order = orderInfoService.selectById(dto.getOrderId());

            //查询订单支付
            Wrapper<OrderPayRelationDTO> orderPayRelation = new EntityWrapper<>();
            orderPayRelation.eq("order_id", order.getId());
            List<OrderPayRelationDTO> payList = orderPayRelationService.selectList(orderPayRelation);

            if (order.getPayType() == ZERO) {
                //查询赊销支付方式
                OrderPaymentTypeDTO orderPaymentTypeDTO = orderPaymentTypeService.getOrderPaymentByOrderIdAndPaymentType(dto.getOrderId(),2);
                if(null != orderPaymentTypeDTO){
                    if (isNull(payList)) {
                        log.info("暂无订单支付信息，修改失败!");
                        throw new RuntimeException("暂无订单支付信息，修改失败!");
                    }
                    updatePaymentScalePrice(order,order.getActualMoney());
                }else{
                    //全款不算首付款，直接改支付金额
                    OrderPayRelationDTO one = orderPayRelationService.selectOne(orderPayRelation);
                    OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                    updateOrderPay.setId(one.getId());//id
                    updateOrderPay.setRealPayMoney(order.getActualMoney());//实付金额
                    updateOrderPay.setCommissionMoney(order.getCommissionMoney());//佣金
                    boolean b = orderPayRelationService.updateById(updateOrderPay);
                    if (!b) {
                        log.info("修改订单支付金额失败!");
                        throw new RuntimeException("修改订单支付金额失败!");
                    }
                }

            } else {
                //分期付款需要重新计算首付款金额
                CommodityInfoDTO goods = commodityInfoService.selectById(dto.getCommodityId());
                //首款比例
                BigDecimal g = new BigDecimal(goods.getFirstBalance()).setScale(TWO, BigDecimal.ROUND_UP);
                //尾款比例
                BigDecimal f = new BigDecimal(goods.getTailBalance()).setScale(TWO, BigDecimal.ROUND_UP);
                //首款
                BigDecimal firstActualMoney = order.getActualMoney()
                        .multiply(g.divide(new BigDecimal(100), TWO));
                //尾款
                BigDecimal tailActualMoney = order.getActualMoney()
                        .multiply(f.divide(new BigDecimal(100), TWO));
                //首款分润
                BigDecimal firstCommission = order.getCommissionMoney()
                        .multiply(g.divide(new BigDecimal(100), TWO));
                //尾款分润
                BigDecimal tailCommission = order.getCommissionMoney()
                        .multiply(f.divide(new BigDecimal(100), TWO));

                if (isNull(payList)) {
                    log.info("暂无订单支付信息，修改失败!");
                    throw new RuntimeException("暂无订单支付信息，修改失败!");
                }
                for (OrderPayRelationDTO payRelationDTO : payList) {
                    if (payRelationDTO.getPeriods() == ONE) {
                        //首款
                        OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                        updateOrderPay.setId(payRelationDTO.getId());//id
                        updateOrderPay.setRealPayMoney(firstActualMoney);//实付金额
                        updateOrderPay.setCommissionMoney(firstCommission);//佣金
                        boolean b = orderPayRelationService.updateById(updateOrderPay);
                        if (!b) {
                            log.info("修改订单支付金额失败!");
                            throw new RuntimeException("修改订单支付金额失败!");
                        }
                    } else {
                        //尾款
                        OrderPayRelationDTO updateOrderPay = new OrderPayRelationDTO();
                        updateOrderPay.setId(payRelationDTO.getId());//id
                        updateOrderPay.setRealPayMoney(tailActualMoney);//实付金额
                        updateOrderPay.setCommissionMoney(tailCommission);//佣金
                        boolean b = orderPayRelationService.updateById(updateOrderPay);
                        if (!b) {
                            log.info("修改订单支付金额失败!");
                            throw new RuntimeException("修改订单支付金额失败!");
                        }
                    }
                }
                // 查询订单合同
                Wrapper<OrderContractParamRelationDTO> contractWrapper = new EntityWrapper<>();
                contractWrapper.eq("order_id", order.getId());
                OrderContractParamRelationDTO orderContractParamRelationDTO = orderContractParamRelationService.selectOne(contractWrapper);
                if (null == orderContractParamRelationDTO) {
                    log.info("暂无订单合同信息!");
                    throw new RuntimeException("暂无订单合同信息,修改失败!");
                }
                OrderContractParamRelationDTO updateContract = new OrderContractParamRelationDTO();
                updateContract.setId(orderContractParamRelationDTO.getId());
                updateContract.setFirstMoney(firstActualMoney);
                updateContract.setTailMoney(tailActualMoney);
                orderContractParamRelationService.updateById(updateContract);
            }
        }
        return true;
    }


    /*
     * @description:赊销类型修改订单询价商品价格
     * @author: chenyu.wang
     * @date: 2020-08-18
     * @param:
     * @return:
     */
    public boolean updatePaymentScalePrice(OrderInfoDTO order,BigDecimal price) {

        Wrapper<OrderPaymentScaleDTO> orderPaymentScaleDTOWrapper = new EntityWrapper<>();
        orderPaymentScaleDTOWrapper.eq("order_id", order.getId());
        List<OrderPaymentScaleDTO> orderPaymentScaleDTOList = orderPaymentScaleService.selectList(orderPaymentScaleDTOWrapper);
        BigDecimal actualMoneyTotal = new BigDecimal(0.00);
            for (int i=0;i<orderPaymentScaleDTOList.size();i++) {
                OrderPaymentScaleDTO orderPaymentScaleDTO = orderPaymentScaleDTOList.get(i);
                //付款比例
                BigDecimal g = orderPaymentScaleDTO.getPaymentScale().setScale(TWO, BigDecimal.ROUND_UP);

                //订单表格单价
                BigDecimal paymentAmount = price
                        .multiply(g).setScale(2,BigDecimal.ROUND_HALF_UP);

                if(i != orderPaymentScaleDTOList.size() - 1){
                    actualMoneyTotal = actualMoneyTotal.add(paymentAmount);
                }else{
                    paymentAmount = price.subtract(actualMoneyTotal);
                }

                orderPaymentScaleDTO.setPaymentTotal(price);
                orderPaymentScaleDTO.setPaymentAmount(paymentAmount);
                orderPaymentScaleDTO.setContractAmount(paymentAmount);//合同金额和付款金额一致，只有发生退款的时候付款金额会变化

                boolean b = orderPaymentScaleService.updateById(orderPaymentScaleDTO);
                if (!b) {
                    log.info("修改订单支付金额失败!");
                    throw new RuntimeException("修改订单支付金额失败!");
                }

            }
        return true;
    }

    /**
     * @return : boolean
     * @Author :chenyu.wang
     * @Description : 修改订单发票金额
     * @Date : 2021.02.26 16:51
     * @Param : [orderId, price]
     **/
    private boolean modifyInvoiceAmount(Long orderId, BigDecimal price) {
        // 查询订单发票，有则修改，无则跳过
        Wrapper<OrderInvoiceDTO> invoiceWrapper = new EntityWrapper<>();
        invoiceWrapper.eq("order_id", orderId);
        OrderInvoiceDTO orderInvoiceDTO = orderInvoiceService.selectOne(invoiceWrapper);
        if (orderInvoiceDTO == null) {
            return true;
        }
        OrderInvoiceDTO invoiceUpdateDto = new OrderInvoiceDTO();
        invoiceUpdateDto.setId(orderInvoiceDTO.getId());
        invoiceUpdateDto.setInvoicePrice(price);
        return orderInvoiceService.updateById(invoiceUpdateDto);
    }
}
